package com.newlink.building.main.ui

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.view.GestureDetector
import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.view.WindowManager
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.lifecycle.lifecycleScope
import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter
import com.newlink.building.library_rino.ConnectionController
import com.newlink.building.common_base.constant.Base_Constant
import com.newlink.building.common_base.constant.Base_RouterPath
import com.newlink.building.common_base.event.HandleAlarmActionRequest
import com.newlink.building.common_base.event.MessageEvent
import com.newlink.building.common_base.event.OpenDoorActionBean
import com.newlink.building.common_base.event.Base_SendMqttMsgEvent
import com.newlink.building.common_base.event.TYPE_APP_BACKGROUND
import com.newlink.building.common_base.event.TYPE_INCOMING_CALL_RECEIVE
import com.newlink.building.common_base.ext.getBoolean
import com.newlink.building.common_base.model.bean.Base_MqttConnectWrapper
import com.newlink.building.common_base.model.bean.MqttData
import com.newlink.building.common_base.model.bean.UserInfoData
import com.newlink.building.common_base.utils.Base_Preference
import com.newlink.building.main.R
import com.newlink.building.main.other.Module_Main_MainConstants
import com.newlink.building.main.other.Module_Main_MainConstants.COMMAND_DISCONNECT_MQTT
import com.newlink.building.main.service.MqttV5Service
import com.newlink.building.NL_App.Companion.coreContext
import com.newlink.building.activities.Module_Phone_GenericActivity
import com.newlink.building.manager.Module_Phone_VoipController
import com.newlink.building.notifications.NotificationsManager
import com.newlink.building.push.MessageIntentService
import com.tencent.mm.opensdk.utils.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.linphone.core.Call
import org.linphone.core.Core
import org.linphone.core.CoreListenerStub
import java.util.Timer
import java.util.TimerTask
import kotlin.math.abs


/**
 * Created by xiaodong on 2024/11/28.
 */
@Route(path = Base_RouterPath.PATH_FCMINCOMINGCALL)
class Module_Main_FcmIncomingCallActivity : Module_Phone_GenericActivity() {

    protected var mqttDataCache: MqttData by Base_Preference(
        Base_Constant.MQTT_INFO_KEY,
        MqttData()
    )

    protected var userInfoData: UserInfoData by Base_Preference(
        Base_Constant.USER_INFO_KEY,
        UserInfoData()
    )

    private var timer: Timer? = null
    private var countDownTime: Long = 30000L
    private var rlContainer: RelativeLayout? = null
    private var rlCallBar: RelativeLayout? = null
    private lateinit var gestureDetector: GestureDetector


    val notificationsManager: NotificationsManager by lazy {
        NotificationsManager(applicationContext)
    }

    @SuppressLint("WrongConstant")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        EventBus.getDefault().register(this)

        val title = intent.getStringExtra("fcm_title")
        val message = intent.getStringExtra("fcm_message")
        val callId = intent.getStringExtra("fcm_callId")
        val cancel = intent.getBoolean("fcm_cancel")
        if (cancel) {
            stopMqttService()
            finish()
        }
        setContentView(R.layout.fcm_incoming_call_activity)
        val attributes = window.attributes
//        attributes.flags = 0x680080

        attributes.flags =
            (WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
                    or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON or
                    WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)

        this.window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
//        this.window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
        this.window.setGravity(Gravity.TOP or Gravity.CENTER_HORIZONTAL)
//        setFinishOnTouchOutside(true)

        findViewById<TextView>(R.id.tv_call_title).text = title
        findViewById<TextView>(R.id.tv_call_info).text = message

        rlContainer = findViewById(R.id.rl_container)
        rlCallBar = findViewById(R.id.rl_call_bar)

        gestureDetector = GestureDetector(this, CallBarGestureListener())
        rlCallBar?.setOnTouchListener { _, event ->
            // 将触摸事件传递给 GestureDetector
            var isConsume = gestureDetector.onTouchEvent(event)
            // 处理点击事件
            if (!isConsume && event.action == MotionEvent.ACTION_UP) {
                rlCallBar?.performClick()
            }
            true
        }

        rlCallBar?.setOnClickListener {
            EventBus.getDefault().post(MessageEvent(TYPE_APP_BACKGROUND, false))
            ARouter.getInstance().build(Base_RouterPath.PATH_HOME).navigation()
            finish()
        }
        coreContext.core.addListener(coreListener)
        startTimer()
        registerSipAccount()
        Log.e("FcmIncomingCallActivity", "onCreate")
        val mqttConnectWrapper = Base_MqttConnectWrapper(
            mqttDataCache.url,
            mqttDataCache.userName,
            accessToken,
            userId
        )
        //离线来电时为防止异常情况,先清除下Rino缓存
        ConnectionController.getInstance(applicationContext).clearCacheAtBeginning()
        startMqttService(applicationContext, mqttConnectWrapper)
    }

    private inner class CallBarGestureListener : GestureDetector.SimpleOnGestureListener() {
        private val SWIPE_THRESHOLD = 100
        private val SWIPE_VELOCITY_THRESHOLD = 100

        override fun onFling(
            e1: MotionEvent?,
            e2: MotionEvent,
            velocityX: Float,
            velocityY: Float,
        ): Boolean {
            val diffX = e2.x - (e1?.x ?: 0f)
            val diffY = e2.y - (e1?.y ?: 0f)
            val absDiffX = abs(diffX)
            val absDiffY = abs(diffY)

            if (absDiffX > absDiffY) {
                if (absDiffX > SWIPE_THRESHOLD && abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffX > 0) {
                        onSwipeRight()
                    } else {
//                        onSwipeLeft()
                    }
                    return true
                }
            } else {
                if (absDiffY > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
//                        onSwipeDown()
                    } else {
                        onSwipeUp()
                    }
                    return true
                }
            }
            return false
        }
    }

    private fun onSwipeRight() {
        finish()
    }

    private fun onSwipeUp() {
        finish()
    }


    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        val cancel = intent.getBoolean("fcm_cancel")
        if (cancel) {
            stopMqttService()
            finish()
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEventMsgReceived(event: MessageEvent) {
        when (event.msgType) {
            TYPE_INCOMING_CALL_RECEIVE -> {
                Log.e("FcmIncomingCallActivity", "onEventMsgReceived TYPE_INCOMING_CALL_RECEIVE")
                hideNotify()
            }
        }
    }

    //收到离线时MainActivity可能未启动,需要再次注册下
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onSendMqttEvent(event: Base_SendMqttMsgEvent) {
        val bean = event.bean

        var msgType = when (bean) {
            is OpenDoorActionBean -> 1
            is HandleAlarmActionRequest -> 2
            else -> 0
        }
        Log.e(
            "FcmIncomingCallActivity",
            "操作 MqttV5Service from ${javaClass.simpleName} <onSendMqttEvent> content is $bean"
        )
        val i = Intent(this@Module_Main_FcmIncomingCallActivity, MqttV5Service::class.java).apply {
            action = Module_Main_MainConstants.COMMAND_MQTT_SENDMSG
            putExtra("send_mqtt_request_bean", bean)
            putExtra("send_mqtt_request_type", msgType)
        }
        startService(i)
    }

    fun clearPushCallNotify() {
//        notificationsManager.dismissMissedCallNotification()
        // 取消推送的来电通知
        val service = Intent(this, MessageIntentService::class.java).apply {
            action = Base_Constant.ACTION_CANCEL_PUSH_CALL_NOTIFICATION
        }
        startService(service)
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        if (event?.action == MotionEvent.ACTION_UP) {
            finish()
        }
        return super.onTouchEvent(event)
    }

    private fun registerSipAccount() {
        val manager = Module_Phone_VoipController.get()
        if (!manager.isAccountExis()) {
            // 暂时先固定端口号,使用随机端口randomPort每次启动应用都需要更新sip代理端口
            manager.registerAccount(
                username = agoraId.toString(),
                displayName = userInfoData.name,
                port = Base_Constant.NETWORK_LISTEN_PORT.toString()
            )
        } else {
            manager.delete()
            registerSipAccount()
        }
    }

    private fun startMqttService(
        context: Context,
        mqttObj: Base_MqttConnectWrapper,
    ) {
        val i = Intent(context, MqttV5Service::class.java).apply {
            action = Module_Main_MainConstants.COMMAND_CONNECT_MQTT
            putExtra(Module_Main_MainConstants.FROM_FCM_CALL, true)
            putExtra(Module_Main_MainConstants.COMMAND_MQTT_OBJ_BUNDLE, mqttObj)
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(i)
        } else {
            context.startService(i)
        }
    }

    private fun stopMqttService() {
        Log.e("FcmIncomingCallActivity", "stopMqttService")
        Intent(this, MqttV5Service::class.java).apply {
            action = COMMAND_DISCONNECT_MQTT
            putExtra(Module_Main_MainConstants.FROM_FCM_CALL, true)
//            stopService(this)
            startService(this)
        }
    }

    private val coreListener = object : CoreListenerStub() {
        override fun onCallStateChanged(
            core: Core,
            call: Call,
            state: Call.State,
            message: String,
        ) {
            when (state) {
                Call.State.End -> {
                    hideNotify()
                }

                Call.State.Error, Call.State.Released -> {
                    finish()
                }

                else -> {}
            }

        }
    }

    override fun onDestroy() {
        super.onDestroy()
        coreContext.core.removeListener(coreListener)
        EventBus.getDefault().unregister(this)
        timer?.cancel()
        timer = null
    }

    private fun startTimer() {
        timer?.cancel()
        timer = Timer("Mqtt connect timeout")
        timer?.schedule(
            object : TimerTask() {
                override fun run() {
                    // Decline call update
                    lifecycleScope.launch {
                        withContext(Dispatchers.Main) {
                            hideNotify()
                        }
                    }
                }
            },
            countDownTime
        )
    }

    private fun hideNotify() {
        clearPushCallNotify()
        rlContainer?.visibility = View.INVISIBLE
    }
}